﻿using System.Net;
using Enyim.Caching;
using Enyim.Caching.Configuration;
using Enyim.Caching.Memcached;
using TY.UC.Common.Extension;
using System.Web;
using System;

namespace TY.UT.Cache.MemCache
{
    interface ICache
    {
        object GetObject(string pKey);
        bool SetObject(string pKey, object pValue, int pExpriesAt = 60);
        bool RemoveObject(string pKey);
    }
    /// <summary>
    /// Membcached配置
    /// </summary>
    public sealed class MemCached : ICache
    {
        private static MemcachedClient _memClient;
        private static readonly object Padlock = new object();
        private static readonly string RunEnv = "RunEnv".GetStrValue(); //Product表示正式环境
        private static readonly string AliAddress = "AliAddress".GetStrValue();
        private static readonly int AliPort = "AliPort".GetIntValue();
        private static readonly string AliCacheUserName = "AliCacheUserName".GetStrValue();
        private static readonly string AliCachePassword = "AliCachePassword".GetStrValue();
        private static readonly int AliMinPoolSize = "AliMinPoolSize".GetIntValue();
        private static readonly int AliMaxPoolSize = "AliMaxPoolSize".GetIntValue();
        private static readonly string KeyRule = "KeyRule".GetStrValue(); //Key规则

        /// <summary>
        /// 线程安全的单例模式
        /// </summary>
        /// <returns></returns>
        public static MemcachedClient GetInstance()
        {
            if (_memClient != null) return _memClient;
            lock (Padlock)
            {
                if (_memClient == null)
                {
                    MemClientInit();
                }
            }
            return _memClient;
        }

        private static void MemClientInit()
        {
            //开发内网测试用的配置
            if (RunEnv != "Product")
            {
                _memClient = new MemcachedClient("enyim.com/memcached");
            }
            else
            {
                IPAddress newaddress = IPAddress.Parse(AliAddress);
                //初始化正式缓存
                MemcachedClientConfiguration memConfig = new MemcachedClientConfiguration();
                // 配置文件 - ip
                memConfig.Servers.Add(new IPEndPoint(newaddress, AliPort));
                // 配置文件 - 协议
                memConfig.Protocol = MemcachedProtocol.Binary;
                //配置文件-权限
                memConfig.Authentication.Type = typeof(PlainTextAuthenticator);
                memConfig.Authentication.Parameters["zone"] = "";
                memConfig.Authentication.Parameters["userName"] = AliCacheUserName;
                memConfig.Authentication.Parameters["password"] = AliCachePassword;
                //下面请根据实例的最大连接数进行设置
                memConfig.SocketPool.MinPoolSize = AliMinPoolSize;
                memConfig.SocketPool.MaxPoolSize = AliMaxPoolSize;
                _memClient = new MemcachedClient(memConfig);
            }
        }


       

        /// <summary>
        /// 获取缓存对象
        /// </summary>
        /// <param name="pKey"></param>
        /// <returns></returns>
        public  object GetObject(string pKey)
        {
            if (string.IsNullOrEmpty(pKey))
                return null;
            pKey += KeyRule;
            return GetInstance().Get(pKey);
        }


        /// <summary>
        /// 将数据写入缓存，之后需要完善，加密压缩之类的，然后在客户端进行解密也解压，提高安全性与效率。
        /// </summary>
        /// <param name="pKey"></param>
        /// <param name="pValue">
        ///     Value值：请自行将数据源转换成对应的类型，json之类的
        ///     缓存过期于此日期
        /// </param>
        /// <param name="pExpriesAt">默认60分钟</param>
        /// <returns></returns>
        public  bool SetObject(string pKey, object pValue, int pExpriesAt = 60)
        {
            if (string.IsNullOrEmpty(pKey))
                return false;
            pKey += KeyRule;
            return GetInstance().Store(StoreMode.Set, pKey, pValue, DateTime.Now.AddMinutes(pExpriesAt));
        }

        /// <summary>
        /// 移除缓存
        /// </summary>
        /// <param name="pKey"></param>
        /// <returns></returns>
        public  bool RemoveObject(string pKey)
        {
            if (string.IsNullOrEmpty(pKey))
                return false;

            pKey += KeyRule;
            return MemCached.GetInstance().Remove(pKey);
        }


    }
    /// <summary>
    /// asp.net自带缓存
    /// </summary>
    public sealed class AspNetCacheConfig : ICache
    {
        private static readonly string KeyRule = "KeyRule".GetStrValue(); //Key规则

        public  bool SetObject(string pKey, object pValue, int pExpriesAt = 60)
        {
            if (string.IsNullOrEmpty(pKey))
                return false;
            pKey += KeyRule;
            HttpRuntime.Cache.Insert(pKey, pValue, null, DateTime.Now.AddMinutes(pExpriesAt), System.Web.Caching.Cache.NoSlidingExpiration);
            return true;
        }

        public  object GetObject(string pKey)
        {
            if (string.IsNullOrEmpty(pKey))
                return null;
            pKey += KeyRule;
            return HttpRuntime.Cache.Get(pKey);
        }

        public  bool RemoveObject(string pKey)
        {
            if (HttpRuntime.Cache.Remove(pKey) == null)
                return false;
            return true;
        }
    }



}
